<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<!-- call、apply、bind区别 -->
		<!-- 三者都可以修改方法的this指向 -->
		<!-- 
		apply
		第二个参数是数组类型的
		call
		传入的是参数列表
		bind
		返回的是改变this指向的函数
		 -->
		<!-- 
		  普通函数，this指向他的调用者
		  非严格模式下，没找到直接调用者，this指向window
		  严格模式下，没找到直接调用者，this是undefined
		  在node中，指向global
		  -->
		<!-- 
		  箭头函数
		  箭头函数没有自己的this指向,他的this是继承而来的；默认指向在定义它时所处的对象，父级作用域。
		  看箭头函数的外层有没有函数，有函数，this继承该函数；没函数，this就是window。
		  不可以当做构造函数
		  不可以使用arguments对象
		  不可以用apply、bind、call方法改变其this指向
		   -->
		<!-- 
			new创建对象如果函数constructor 没有返回对象的话，this指向的是new之后得到的实例
			new创建对象如果函数constructor 返回对象的话，this指向的事构造函数本身
			-->
		<script>
			// 字面量对象中的this
			// var num = 1
			// var obj = {
			// 	num: 2,
			// 	fun1() {
			// 		console.log(this)
			// 		return this.num * 2
			// 	},
			// 	fun2: () => {
			// 		console.log(this)
			// 		return this.num * 5
			// 	}
			// }
			// obj.fun1() //4，this指向fun1的调用者obj
			// obj.fun2() //5，fun2定义的环境是window


			let length = 10;
			function fn() {
				console.log(this.length)
			}
			var obj = {
				length: 5,
				method(fn) {
					fn();
					arguments[0]();
				},
				method1:function() {
					console.log(this.length)
				},
			}
			console.log(length)//10
			console.log(this.length)//0   let声明的变量不会在window对象上
			obj.method(fn); //0 1    arguments[0]()调用数组中的方法，arguments调用方法fn，所以this指向arguments数组。
			obj.method1(fn); //5



			// var a = 1
			// var obj = {
			//   a: 2,
			//   func2: () => {
			//     console.log(this.a)
			//   },

			//   func3: function() {
			//     console.log(this.a)
			//   }
			// }

			// var func1  = () => {
			//   console.log(this.a)
			// }

			// var func2 = obj.func2

			// var func3 = obj.func3

			// func1() //1
			// func2() //1
			// func3() //1
			// obj.func2() //1
			// obj.func3() //2




			// var a = 1,
			// obj = {
			// 	a: 2,
			// 	b1:function(){
			// 		console.log(this.a);
			//     },
			//     b2:()=>{
			//         console.log(this.a);
			//     },
			// 	c1:function(){
			// 		return function(){
			// 			console.log(this.a);
			// 		}
			//     },
			//     c2:()=>{
			//         return function () {
			//             console.log(this.a)
			//         }
			//     },
			//     c3:()=>{
			//         return ()=>{
			//             console.log(this.a)
			//         }
			//     },
			//     c4:()=>{
			//         return console.log(this.a)
			//     }
			// }

			// obj.b1(); //2
			// obj.b2(); //1
			// obj.b1.call(window); //1
			// var str = obj.c1();
			// str(); //1,指向函数的调用者,window
			// window.obj.c1()(); //1
			// obj.c2()(); //1
			// obj.c3()(); //1
			// obj.c4();  //1



			// var name = 'win',
			// obj = {
			//     name: 'o',
			//     fun1:()=>{
			// 		this.name = "win1";
			//         console.log(this.name)
			//     },
			//     fun2:function () {
			//         console.log(this.name)
			//     }
			// }
			// console.log(this.name);//win
			// obj.fun1(); //win1
			// obj.fun2(); //o
			// console.log(this.name); //win1



			// var name = 'win';
			// function Obj() {
			//     this.name = 'o';
			//     this.fun1 = function () {
			//         console.log(this.name)
			//     }
			//     this.fun2 = () => {
			//         console.log(this.name)
			//     }
			// }

			// var obj = new Obj();
			// console.log(obj);
			// obj.name; //o
			// obj.fun1();//o
			// obj.fun2(); //o

			// var _fun1 = obj.fun1;
			// _fun1(); //win
			// var _fun2 = obj.fun2;
			// _fun2();//o



			//new创建对象如果函数constructor 没有返回对象的话，this指向的是new之后得到的实例
			//new创建对象如果函数constructor 返回对象的话，this指向的事构造函数本身
			// function foo(a) {
			//   this.a = a;
			//   console.log(this)//foo{a:2}
			// }
			// const f = new foo(2);
			// f.a; //2

			// function bar(a) {
			//   this.a = a;
			//   return {
			//     a: 100
			//   };
			// }
			// const b = new bar(3);
			// b.a; // 100


			// var a = 1;
			// function fn1(){
			// 	console.log(this.a)
			// }
			// fn1();//1 普通函数，this指向他的调用者,fn1()可以写成window.fn(),所以window是他的调用者。
			// const obj1 = {
			//   a: 3,
			//   fn: function() {
			//     console.log(this.a);
			//   }
			// };
			// obj1.fn() // 3 obj1是他的调用者，所以this指向obj1
			// const fn2 = obj1.fn; 
			// fn2(); //1 将引用给了fn1，等同于写了 function fn1() { console.log(this.a); },所以this指向window
			// setTimeout(obj1.fn, 1000); // 1 定时器里的函数this指向window
			// function run(fn) {
			//   fn();
			// }
			// run(obj1.fn); // 1, 传进去的是一个引用
		</script>
	</body>
</html>